﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ClusterAggregation.GeneralTools
{
    using ClusterAggregation.Datum;
    using ClusterAggregation.DataSets;
    /**
    * This class enables one to read a dataset from a file.
    */
    public class CDatasetReader
    {
        /**
        * reading a simple dataset from a file
        * @param filename (string) [IN] the name of the file we will write.
        * @return dataset (AData[])
        */
        public static ClusterAggregation.Datum.AData[] readDataArray(string filename)
        {
            List<ClusterAggregation.Datum.AData> objs = new List<ClusterAggregation.Datum.AData>();

            TextReader tr = new StreamReader(filename);
            try
            {
                int Pid = 0;
                char[] delimiters = new char[] { '\t', ' ' };
                do
                {
                    //string str = .Trim();
                    string str = System.Text.RegularExpressions.Regex.Replace(tr.ReadLine(), @"\s+", " ");
                    string[] args = str.Trim().Split(delimiters);

                    int dim = args.Length;
                    AData tmp = new ClusterAggregation.Datum.AData(dim);

                    for (int i = 0; i < dim; i++)
                    {
                        tmp.coordinates[i] = Double.Parse(args[i]);
                    }

                    tmp.id = Pid++;
                    objs.Add(tmp);

                } while (tr.Peek() >= 0);
            }
            finally
            {
                tr.Close();
            }
            
            return objs.ToArray();
        }

        /**
       * reading a clustered dataset from a file
       * @param filename (string) [IN] the name of the file we will write.
       * @return partition (CPartition) 
       */
        public static ClusterAggregation.DataSets.CPartition readParition(string filename)
        {
            ClusterAggregation.DataSets.CPartition partition = new ClusterAggregation.DataSets.CPartition();
            List<ClusterAggregation.Datum.AData> objs = new List<ClusterAggregation.Datum.AData>();

            TextReader tr = new StreamReader(filename);
            try
            {
                partition.name = tr.ReadLine();
                double tmp_anmi = 0;
                double.TryParse(tr.ReadLine(), out tmp_anmi);

                partition.ANMI = tmp_anmi;

                int Pid = 0;
                CCluster clstr = new ClusterAggregation.DataSets.CCluster();

                string str = tr.ReadLine();
                if (str.CompareTo("[") != 0)
                {
                    throw new Exception();
                }
                do
                {
                    str = tr.ReadLine();

                    if ((str.CompareTo("]") == 0) || (tr.Peek() <= 0))
                    {
                        partition.clusters.Add(clstr);

                        if (tr.Peek() == 0)
                        {
                            break;
                        }

                        str = tr.ReadLine();

                        if (str == null) // playing nice with csharp
                        {
                            break;
                        }


                        if (str.CompareTo("[") == 0)
                        {
                            clstr = new ClusterAggregation.DataSets.CCluster();
                        }
                        else if (str.CompareTo("]") == 0)
                        {
                            break;
                        }
                        else //throw new Exception();
                        {
                            break;
                        }
                    }
                    else // must be a data
                    {
                        string[] args = str.Trim().Split(' ');
                        int dim = args.Length;
                        AData tmp = new ClusterAggregation.Datum.AData(dim);

                        for (int i = 0; i < dim; i++)
                        {
                            tmp.coordinates[i] = Double.Parse(args[i]);
                        }

                        tmp.id = Pid++;
                        clstr.data.Add(tmp);
                    }

                } while (tr.Peek() >= 0);
            }
            finally
            {
                tr.Close();
            }
            return partition;
        }
    }
}
